package com.yonyou.pmclouds.projectpart.processor;

import com.yonyou.pmclouds.basecom.bp.processor.SingleProcessor;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.projectpart.entity.ProjectPartVO;
import com.yonyou.pmclouds.projectpart.mapper.ProjectpartMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 工程部位添加默认数据
 * 数据为树级结构，为方便查询和前台使用，实体中添加了内码，在新增数据时，需要根据父内码为当前数据添加内码（每一级预留3位，业务上限制共4级）
 * 例：父级内码：000  当前内码 000000
 */
@Component
public class ProjectpartFillDataProcessor implements SingleProcessor<ProjectPartVO>{

    @Autowired
    private ProjectpartMapper projectpartMapper;

    @Override
    public void process(ProjectPartVO vo, ProjectPartVO orig) throws BusinessException {
        if(StringUtils.isEmpty(vo.getPkTenant())){
            vo.setPkTenant(RuntimeEnvironment.getTenantId());
        }
        String nextInnerCode  = getProjectNextInnerCode(vo);
        //校验生成工程部位编码的有效性
        CheckInnerCodeValid(vo.getScode(), nextInnerCode);
        vo.setInnerCode(nextInnerCode);
        if(StringUtils.isEmpty(vo.getScode())){
            vo.setScode("Y" + vo.getInnerCode());
        }
    }



    public  String getProjectNextInnerCode(ProjectPartVO vo){
        String dbMaxInnerCode = getDBMaxInnerCode(vo);
        ProjectPartVO parent = null;
        if(StringUtils.isNotEmpty(vo.getPkParent())){
            parent = projectpartMapper.getById(vo.getPkParent());
        }
        String nextInnerCode = getNextInnerCode(StringUtils.isEmpty(dbMaxInnerCode)?3:dbMaxInnerCode.length(),
                dbMaxInnerCode,parent==null?null:parent.getInnerCode());
        return nextInnerCode;
    }

    public String getDBMaxInnerCode(ProjectPartVO vo){
        Integer innerLength = null;
        String parentInnerCode = null;
        if(!StringUtils.isEmpty(vo.getPkParent())){
            ProjectPartVO parentVO = projectpartMapper.getById(vo.getPkParent());
            if(parentVO != null){
                parentInnerCode = parentVO.getInnerCode();
            }
        }
        if(StringUtils.isEmpty(parentInnerCode)){
            innerLength = 3;
        }else{
            innerLength = 3+parentInnerCode.length();
        }
        ProjectPartVO qryVO = new ProjectPartVO();
        vo.setPkTenant(vo.getPkTenant());
        qryVO.setPkProject(vo.getPkProject());
        if(parentInnerCode != null){
            qryVO.setInnerCode(parentInnerCode+"%");
        }
        qryVO.setInnerCodeLen(innerLength);
        String maxInnerCode = projectpartMapper.queryProjectMaxInnerCode(qryVO);
        return maxInnerCode;
    }

    /**
     * 校验生成工程部位编码的有效性
     * @param scode
     * @param nextInnerCode
     * @throws BusinessException
     */
    private void CheckInnerCodeValid(String scode, String nextInnerCode) throws BusinessException {
        if(StringUtils.isEmpty(nextInnerCode)){
            throw new BusinessException("生成工程部位内码失败");
        }
        if(nextInnerCode.length() % 3 != 0){
            throw new BusinessException("生成工程部位内码失败");
        }
        Integer levels = nextInnerCode.length() / 3;
        for(int i = 0; i< levels; i++){
            String subInnerCode = nextInnerCode.substring(i*3,(i+1)*3);
            if(Integer.valueOf("999") - Integer.valueOf(subInnerCode) < 0){
                if(StringUtils.isEmpty(scode)){
                    throw new BusinessException((i+1)+"级工程部位数据超过999个，请联系管理员进行扩容！");
                }else{
                    //web端有虚拟根节点，在计算层级时，比实际层级大一层
                    throw new BusinessException((i+2)+"级工程部位数据超过999个，请联系管理员进行扩容！");
                }
            }
        }
    }

    /**
     *  根据传入的${numStr}获取+1后的字符串（numStr为一串数字）
     * @param length
     * @param numStr    数据库查询到的最大内码
     * @param parentInnerCode   父内码
     * @return
     */
    public  String getNextInnerCode(Integer length,String numStr,String parentInnerCode){
        if(StringUtils.isEmpty(numStr)){
            if(StringUtils.isEmpty(parentInnerCode)){
                return "000";
            }else{
                return parentInnerCode.trim() + "000";
            }
        }
        Integer num =  Integer.valueOf(numStr);
        ++num;
        String numTemp = num.toString();
        if(length > 0){
            String prefix = "";
            for(int i = 0; i< length-numTemp.length();i++){
                prefix += "0";
            }
            return prefix+numTemp;
        }
        return null;
    }


}
